#ifndef RX8010SJ_ADAPTER
    #define RX8010SJ_ADAPTER

    #include "Arduino.h"
	#include "Wire.h"
#ifndef RX8010_I2C_ADDR
#define RX8010_I2C_ADDR 0x32
#endif
    namespace RX8010SJ {
		#define RX8010_SEC     0x10
		#define RX8010_MIN     0x11
		#define RX8010_HOUR    0x12
		#define RX8010_WDAY    0x13
		#define RX8010_MDAY    0x14
		#define RX8010_MONTH   0x15
		#define RX8010_YEAR    0x16
		#define RX8010_RESV17  0x17
		#define RX8010_ALMIN   0x18
		#define RX8010_ALHOUR  0x19
		#define RX8010_ALWDAY  0x1A
		#define RX8010_TCOUNT0 0x1B
		#define RX8010_TCOUNT1 0x1C
		#define RX8010_EXT     0x1D
		#define RX8010_FLAG    0x1E
		#define RX8010_CTRL    0x1F
		/* 0x20 to 0x2F are user registers */
		#define RX8010_RESV30  0x30
		#define RX8010_RESV31  0x31
		#define RX8010_IRQ     0x32

		/* Default values for reseting the module */
		#define RX8010_ADDR17_DEF_VAL 0xD8
		#define RX8010_ADDR30_DEF_VAL 0x00
		#define RX8010_ADDR31_DEF_VAL 0x08
		#define RX8010_ADDR31_DEF_VAL 0x08
		#define RX8010_IRQ_DEF_VAL    0x04
		#define RX8010_CTRL_DEF_VAL   0x04

		#define RX8010_VLF_POS    1
		#define RX8010_TE_POS     4
		#define RX8010_TSEL0_POS  0
		#define RX8010_TSEL1_POS  1
		#define RX8010_TSEL2_POS  2
		#define RX8010_TIE_POS    4
		#define RX8010_TMPIN_POS  2
		#define RX8010_TF_POS     4
		#define RX8010_STOP_POS   6
		#define RX8010_TSTP_POS   2
		#define RX8010_AIE_POS    3
		#define RX8010_WADA_POS   3
		#define RX8010_AF_POS     3
		#define RX8010_USEL_POS   5
		#define RX8010_UF_POS     5
		#define RX8010_UIE_POS    5
		#define RX8010_FSEL0_POS  6
		#define RX8010_FSEL1_POS  7
		#define RX8010_FOPIN0_POS 0
		#define RX8010_FOPIN1_POS 1

		#define RX8010_AL_DISABLED 0b10000000
#define IRQ2 0
#define IRQ1 1
		struct DateTime {
			byte second;
			byte minute;
			byte hour;
			byte dayOfWeek; // Has to be set
			byte dayOfMonth;
			byte month;
			byte year; // Two digits
		};

        class Adapter {
            public:
                // Constructor/destructor
                Adapter(byte i2cSlaveAddr);
                virtual ~Adapter();

                // Methods
				bool initAdapter();
				bool initModule();
				void resetModule(void);
				void toggleGlobalStop(bool stopEnabled);

				// Calendar
                DateTime readDateTime(void);
				void writeDateTime(DateTime dateTime);

				// Fixed cycle interrupt固定频率中断信号，输出为一个低电平信号。当频率为4096Hz时低电平为122us，其它频率时为7.8ms
				/*
				frequency  基础频率
					0b000	4096Hz 
					0b001	64Hz 
					0b010	1Hz 
					0b011	1/60Hz 
					0b100	1/3600Hz
				例如：setFCTCounter(10, 0b001);	输出的频率为6.4Hz
				*/
				
				void setFCTCounter(uint16_t multiplier, byte frequency);
				uint16_t getFCTCounter();
				void setFCTOutput(byte pin);
				void enableFCT();
				void disableFCT();
				bool checkFCT();

				// Alarm
				void setAlarm(DateTime time, byte mode);
				void enableAlarm();
				void disableAlarm();
				bool checkAlarm();

				// Time Update Interrupt
				/*使用IRQ1输出。setTUIMode(bool minute)，1为更新分钟，0为更新秒
				*/
				void setTUIMode(bool minute);
				void enableTUI();
				void disableTUI();
				bool checkTUI();

				// Frequency output
				/*frequency = 	0 OFF
								1 1Hz
								2 1024Hz
								3 32768Hz(只能IRQ1输出）
								*/
				void enableFOUT(byte frequency, byte pin);
				void disableFOUT();

            private:
                byte i2cAddress;

				byte readFromModule(byte address);
				void writeToModule(byte address, byte data);
				void writeFlag(byte address, byte pos, byte value);
				byte getSingleBit(byte binary);
				byte getValueFromBinary(byte binary, byte pos);
				byte getValueFromBinary(byte binary, byte pos, byte val);
				byte sumValueFromBinary(byte binary, byte length);
				byte setEightyBinary(byte binary, byte val);
				byte setFortyBinary(byte binary, byte val);
				byte setTwentyBinary(byte binary, byte val);
				byte setTenBinary(byte binary, byte val);
				byte setBinary(byte binary, byte pos, byte flagVal);
        };
    }

#endif